package com.example.demo.controller;


import com.example.demo.mapper.UserMapper;
import com.example.demo.services.MinioService;
import com.example.demo.services.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.imageio.stream.MemoryCacheImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;


@RestController
@RequestMapping("/file")
public class FileController {

    private final UserService userService;
    private final UserMapper userMapper;
    @Value("${system.file-path}")
    private String path;

    private static final Logger logger = LoggerFactory.getLogger(FileController.class);

    private final MinioService minioService;

    public FileController(MinioService minioService, UserService userService, UserMapper userMapper) {
        this.minioService = minioService;
        this.userService = userService;
        this.userMapper = userMapper;
    }

    @PostConstruct
    public void init() {
//        清理classpath:前缀（如果有）
        path = path.replace("classpath:", "");
        // 如果path为空，使用默认值
        if (path.trim().isEmpty()) {
            path = System.getProperty("java.io.tmpdir") + "/uploads/";
        }
//        规范化路径
        path = path.endsWith(File.separator) ? path : path + File.separator;
//        创建目录
        File dir = new File(path);
        if (!dir.exists() && !dir.mkdirs()) {
            throw new IllegalStateException("无法创建文件存储目录: " + path);
        }
        if (!dir.canWrite()) {
            throw new IllegalStateException("文件存储目录不可写: " + path);
        }
    }

    @PostMapping("/upload-avatar")
    public ResponseEntity<Map<String, Object>> uploadFile(@RequestParam("userId") String userId, @RequestParam("avatarFile") MultipartFile file) {
        Map<String, Object> response = new HashMap<>();
        Map<String, Object> data = new HashMap<>();     // data层
        try {
            //        检查文件是否为空
            if (file.isEmpty()) {
                data.put("success", false);
                data.put("message", "文件不能为空！");
                response.put("data", data);
                return ResponseEntity.badRequest().body(response);
            }

            // 内存中转换格式
            BufferedImage image = ImageIO.read(file.getInputStream());
            if (image == null) {
                data.put("message", "无法读取图片文件");
                return ResponseEntity.badRequest().body(response);
            }
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ImageIO.write(image, "webp", byteArrayOutputStream);

//            直接上传到minio
            String objectName = userId + "/" + UUID.randomUUID() + ".webp";
            String avatar = minioService.uploadFile(objectName, new ByteArrayInputStream(byteArrayOutputStream.toByteArray()),
                    byteArrayOutputStream.size(), "image/webp", userId);

//            数据库同步更新
            userMapper.updateAvatar(userId, avatar);

            // 构建成功响应
            data.put("success", true);
            data.put("url", avatar);
            data.put("message", "文件上传成功");
            response.put("data", data);
            return ResponseEntity.ok(response);
        } catch (Exception e) {// 构建错误响应
            e.printStackTrace();
            data.put("success", false);
            data.put("message", "文件上传失败：" + (e.getMessage() != null ? e.getMessage() : "请检查文件格式或服务器配置"));
            response.put("data", data);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }

    // 将图片保存至本地     在这里使用java的NIO的Path Api（更现代）
    private String saveFile(MultipartFile file) throws IOException {
        String[] fileStr = Objects.requireNonNull(file.getOriginalFilename()).split("\\.");
        String suffix = fileStr[fileStr.length - 1];
        String fileName = UUID.randomUUID() + "." + suffix;

        Path destination = Paths.get(path).resolve(fileName);
        Files.createDirectories(destination.getParent());

        file.transferTo(destination.toFile());
        return fileName;
    }

}
